﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework;

namespace GameViewer.Core.Controls
{
    class Input : ViewerComponent
    {
        [Flags]
        enum MoveDirection
        {
            Forward = 1,  //W
            Left = 2,     //A
            Backward = 4, //S            
            Right = 8,    //D
            Up = 16,      //Q
            Down = 32     //E
        }

        //MouseState mOldMouseState;
        //KeyboardState mOldKeyboardState;
        bool mControl;
        bool mShift;
        bool mAlt;
        MoveDirection mMove;
        GameViewer.Core.Viewers.MeshViewer mViewer;

        public Input(GameViewer.Core.Viewers.MeshViewer viewer)
        {
            this.mViewer = viewer;
        }

        public override void Update(GameViewer.Core.Viewers.MeshViewer viewer, System.Diagnostics.Stopwatch timer)
        {
            KeyboardState newKeyboardState = Keyboard.GetState();
            MouseState newMouseState = Mouse.GetState();
            
            if (newMouseState.LeftButton == ButtonState.Pressed)
            {
                viewer.Focus();
            }

            // 获取按键
            Keys[] keys = newKeyboardState.GetPressedKeys();

            // 控制键
            mControl = keys.Contains(Keys.LeftControl) || keys.Contains(Keys.RightControl);
            mShift = keys.Contains(Keys.LeftShift) || keys.Contains(Keys.RightShift);
            mAlt = keys.Contains(Keys.LeftAlt) || keys.Contains(Keys.RightAlt);

            // 方向键
            mMove = 0;
            if (keys.Contains(Keys.W) || keys.Contains(Keys.Up))
            {
                mMove |= MoveDirection.Forward;
            }
            if (keys.Contains(Keys.A) || keys.Contains(Keys.Left))
            {
                mMove |= MoveDirection.Left;
            }
            if (keys.Contains(Keys.S) || keys.Contains(Keys.Down))
            {
                mMove |= MoveDirection.Backward;
            }
            if (keys.Contains(Keys.D) || keys.Contains(Keys.Right))
            {
                mMove |= MoveDirection.Right;
            }
            if (keys.Contains(Keys.Q) || keys.Contains(Keys.PageUp))
            {
                mMove |= MoveDirection.Up;
            }
            if (keys.Contains(Keys.E) || keys.Contains(Keys.PageDown))
            {
                mMove |= MoveDirection.Down;
            }

            // 更新视图位置
            this.UpdateCamera();

            // Update saved state.
            //mOldKeyboardState = newKeyboardState;
            //mOldMouseState = newMouseState;
        }

        private void UpdateCamera()
        {
            Vector3 camPos = this.mViewer.CameraLookAt;
            if ((mMove & MoveDirection.Up) == MoveDirection.Up)
            {
                camPos.Y += Settings.MoveSpeed;
            }
            if ((mMove & MoveDirection.Down) == MoveDirection.Down)
            {
                camPos.Y -= Settings.MoveSpeed;
            }
            if ((mMove & MoveDirection.Backward) == MoveDirection.Backward)
            {
                camPos.Z += Settings.MoveSpeed;
            }
            if ((mMove & MoveDirection.Forward) == MoveDirection.Forward)
            {
                camPos.Z -= Settings.MoveSpeed;
            }
            if ((mMove & MoveDirection.Left) == MoveDirection.Left)
            {
                camPos.X -= Settings.MoveSpeed;
            }
            if ((mMove & MoveDirection.Right) == MoveDirection.Right)
            {
                camPos.X += Settings.MoveSpeed;
            }

            this.mViewer.CameraLookAt = camPos;
            this.mViewer.CameraViewMatrix = Matrix.CreateLookAt(
                this.mViewer.CameraPosition,
                this.mViewer.CameraLookAt,
                Vector3.Up);
        }
    }
}
